package halberd.filter;

import halberd.DataType;
import halberd.ImgFilter;
import halberd.data.Complex;
import halberd.data.FourierImgData;
import halberd.data.ImgData;
import halberd.data.ImgDataFactory;
import halberd.utils.FFTUtils;

public class FourierFilter implements ImgFilter {

	public ImgData process(ImgData input) {
		if (!canProcess(input)) {
			return null;
		}
		FourierImgData result = ImgDataFactory.createFourierImgData(input.getWidth(), input.getHeight());
		fourier(input.getDatas(), result.getCpDatas(), result.getDatas(), result.getFWidth(),result.getFHeight());
		result.setDataType(DataType.FOURIERED);
		return result;
	}

	private boolean canProcess(ImgData input) {
		if (input == null) {
			return false;
		}
		DataType dt = input.getDataType();
		if (dt == DataType.GRAY) {
			return true;
		}
		return false;
	}

	private void fourier(int[][][] src, Complex[] dst, int[][][] dst0,int fw,int fh) {
		Complex[] temp = new Complex[dst.length];
		for (int i = 0; i < fh; i++) {
			for (int j = 0; j < fw; j++) {
				temp[i * fw + j] = new Complex(src[j][i][4], 0);
				dst[i * fw + j] = new Complex();
			}
		}
		for (int i = 0; i < fh; i++) {
			FFTUtils.fft(temp, i, fw, dst);
		}
		for (int i = 0; i < fh; i++) {
			for (int j = 0; j < fw; j++) {
				temp[j * fh + i] = dst[i * fw + j];
			}
		}
		// 对x方向进行傅立叶变换
		for (int i = 0; i < fw; i++) {
			FFTUtils.fft(temp, i, fh, dst);
		}

		for (int i = 0; i < fh; i++) {
			for (int j = 0; j < fw; j++) {
				double re = dst[j * fh + i].re;
				double im = dst[j * fh + i].im;
				int ii = 0, jj = 0;
				int tmp = (int) (Math.sqrt(re * re + im * im) / 100);
				if (tmp > 255) {
					tmp = 255;
				}
				if (i < fh / 2) {
					ii = i + fh / 2;
				} else {
					ii = i - fh / 2;
				}
				if (j < fw / 2) {
					jj = j + fw / 2;
				} else {
					jj = j - fw / 2;
				}
				dst0[jj][ii][4] = tmp;
			}
		}
	}
}
